package com.sky.utils;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.io.ByteArrayInputStream;
/**
 * 1. 当前包名: com.sky.utils    存放工具类相关的类
 * 2. 当前类名: AliOssUtil    阿里云 OSS 工具类
 */

/**
 * AliOssUtil; 封装了阿里云 OSS 的文件上传操作。
 * 该类提供了上传文件到阿里云 OSS 的功能，并生成上传后的文件 URL。
 */
@Data
@AllArgsConstructor
@Slf4j
public class AliOssUtil {
    /**
     * * 知识点:
     * 1. `@Data`：来自 Lombok 的注解，自动生成类的 `getter`、`setter`、`toString()`、`equals()` 和 `hashCode()` 等方法，减少样板代码。
     * 2. `@AllArgsConstructor`：来自 Lombok 的注解，自动生成一个包含所有字段的构造方法。
     * 3. `@Slf4j`：来自 Lombok 的注解，自动为类生成一个 `log` 实例，便于记录日志。
     * 4. `OSSClientBuilder`：这是阿里云 OSS SDK 提供的客户端构建器，用于创建与 OSS 服务的连接。
     * 5. 阿里云 OSS（对象存储服务）是一个用于存储和管理数据的服务，该工具类封装了上传文件到 OSS 的操作。
     */
    private String endpoint;// 阿里云 OSS 访问的 Endpoint
    private String accessKeyId;// 阿里云访问密钥 ID
    private String accessKeySecret;// 阿里云访问密钥 Secret
    private String bucketName;// 阿里云 OSS 存储桶名称

    /**
     * 文件上传
     *
     * @param bytes
     * @param objectName
     * @return
     */
    public String upload(byte[] bytes, String objectName) {

        // 创建OSSClient实例,连接到阿里云 OSS
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        try {
            // 创建PutObject请求,将文件上传到 OSS
            ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(bytes));
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            // 关闭 OSS 客户端连接
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }

        //文件访问路径规则 https://BucketName.Endpoint/ObjectName
        StringBuilder stringBuilder = new StringBuilder("https://");
        stringBuilder
                .append(bucketName)// 添加桶名
                .append(".")
                .append(endpoint)// 添加 endpoint
                .append("/")// 路径分隔符
                .append(objectName);// 添加上传文件的 objectName


        log.info("文件上传到:{}", stringBuilder.toString());

        return stringBuilder.toString();
    }
}
/**
 * 仿写：
 * public class AliOssDownloadUtil {
 * private String endpoint;
 *     private String accessKeyId;
 *     private String accessKeySecret;
 *     private String bucketName;
 *     public InputStream download(String objectName) {
 *         // 创建 OSSClient 实例，连接到阿里云 OSS
 *         OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
 *         try {
 *             // 从 OSS 下载文件
 *             InputStream inputStream = ossClient.getObject(bucketName, objectName).getObjectContent();
 *             log.info("文件下载成功，文件名：{}", objectName);
 *             return inputStream;
 *         } catch (OSSException oe) {
 *             // 处理 OSS 异常
 *             log.error("文件下载失败，OSSException: {}", oe.getErrorMessage());
 *         } catch (ClientException ce) {
 *             // 处理客户端异常
 *             log.error("文件下载失败，ClientException: {}", ce.getMessage());
 *         } finally {
 *             // 关闭 OSS 客户端连接
 *             if (ossClient != null) {
 *                 ossClient.shutdown();
 *             }
 *         }
 *         return null;
 *     }
 */